package com.lincoln.service;

import com.lincoln.entity.permission.DbPermission;
import com.lincoln.entity.permission.DbUserPermission;
import com.lincoln.entity.permission.UserPermissionTypeEnum;
import com.lincoln.entity.user.DbUser;
import com.lincoln.repository.UserPermissionRepository;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class UserPermissionService extends BaseService<DbUserPermission, UserPermissionRepository> {
    /**
     * 建立分页排序请求
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    public PageRequest buildPageRequest(int pageNo, int pageSize, Sort.Order... orders) {
        Sort sort = Sort.by(orders);
        return PageRequest.of(pageNo, pageSize, sort);
    }

    public Predicate createPredicate(Root<DbUserPermission> root, CriteriaBuilder cb, Map<String, Object> params) {
        Predicate result = cb.and();
        if (params.get("username") != null) {
            Predicate p = cb.like(root.get("user.username").as(String.class), "%" + params.get("username") + "%");
            result = cb.and(result, p);
        }
        if (params.get("password") != null) {
            Predicate p = cb.like(root.get("user.password").as(String.class), "%" + params.get("password") + "%");
            result = cb.and(result, p);
        }
        if (params.get("enabled") != null) {
            Predicate p = cb.equal(root.get("enabled").as(Boolean.class), params.get("enabled"));
            result = cb.and(result, p);
        }
        if (params.get("nickName") != null) {
            Predicate p = cb.like(root.get("nickName").as(String.class), "%" + params.get("nickName") + "%");
            result = cb.and(result, p);
        }
        return result;
    }

    /**
     * 查询用户的白名单
     *
     * @param userId
     * @return
     */
    public List<DbUserPermission> findUserWhitePermission(long userId) {
        Specification<DbUserPermission> specification = new Specification<DbUserPermission>() {
            @Override
            public Predicate toPredicate(Root<DbUserPermission> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate result = cb.and();
                Predicate p = cb.equal(root.get("user").get("id").as(Long.class), userId);
                result = cb.and(result, p);
                p = cb.equal(root.get("permissionType").as(UserPermissionTypeEnum.class), UserPermissionTypeEnum.WHITE);
                result = cb.and(result, p);
                return result;
            }
        };
        List<DbUserPermission> list = repository.findAll(specification);
        return list;
    }

    /**
     * 查询用户的黑名单
     *
     * @param userId
     * @return
     */
    public List<DbUserPermission> findUserBlackPermission(long userId) {
        Specification<DbUserPermission> specification = new Specification<DbUserPermission>() {
            @Override
            public Predicate toPredicate(Root<DbUserPermission> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate result = cb.and();
                Predicate p = cb.equal(root.get("user").get("id").as(Long.class), userId);
                result = cb.and(result, p);
                p = cb.equal(root.get("permissionType").as(UserPermissionTypeEnum.class), UserPermissionTypeEnum.BLACK);
                result = cb.and(result, p);
                return result;
            }
        };
        List<DbUserPermission> list = repository.findAll(specification);
        return list;
    }

    /**
     * 删除用户黑名单
     * @param userId
     */
    public void removeBlack(long userId) {
        List<DbUserPermission> userPermissions = findUserBlackPermission(userId);
        for (DbUserPermission userPermission : userPermissions) {
            delete(userPermission);
        }
    }
    /**
     * 删除用户黑名单
     * @param userId
     */
    public void removeWhite(long userId) {
        List<DbUserPermission> userPermissions = findUserWhitePermission(userId);
        for (DbUserPermission userPermission : userPermissions) {
            delete(userPermission);
        }
    }
}
